//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES OR INDEMNITIES.
//

#ifndef __CAMPDD_H_INCLUDED__
#define __CAMPDD_H_INCLUDED__
#include "hicamera_misc.h"

#define CPI_POLCLK_POSITIVE 1
#define CPI_POLCLK_NEGATIVE 2
#define CPI_DATA_SWAPBYTES  4
#define CPI_POLRESET_POSITIVE 8
#define CPI_POLRESET_NEGATIVE 0x10

typedef enum {
    STREAM_STOP,
    STREAM_PAUSE,
    STREAM_RUN
} CaptureState;

enum
{
    CAPTURE=0,
    STILL,
    PREVIEW,
    MAX_STREAMS
};

typedef DWORD (WINAPI *IRQ_CALLBACK)(PVOID pContext, PVOID pPDDContext);

typedef struct 
{
    // list of clock speeds available by 
    // camera port interface for ext. camera 
    DWORD *pExClockList;
    // caps flags set by camera port controller
    DWORD  Caps;
    
    // QueryCameraPortInfo asks camera control 
    DWORD DesiredExClock;
    DWORD ActualExClock;
    
    DWORD DesiredCaps;
    DWORD ActualCaps;

} CameraPortInfo;

#define	POSTPROC_DO_NOTHING 0x0		//do nothing
#define POSTPROC_ROT_CW_90 0x2      // rotate clockwise 90 degree
#define POSTPROC_ROT_CC_90 0x4      // rotate counter clockwise 90 degree
#define POSTPROC_HFLIP     0x8      // horizontal flip
#define POSTPROC_VFLIP     0x10     // vertical flip
#define POSTPROC_YV12      0x20     // convert YUV422 to YV12 planar
#define POSTPROC_YV16      0x40     // convert YUV422 to YV16 planar
#define POSTPROC_PIXELSWAP 0x80     // RGB16: swap pixels within DWORD
#define POSTPROC_VYUY      0x100    // VYUY format
#define POSTPROC_JPEG      0x200   // JPEG format


// list of clock speeds of Hisi ICU CAM interface
static DWORD ExClkList[]=  // 240M divede by index
{
    12000000,    //devided by 20(19+1)
    13000000,    
    15000000,
    18000000,
    20000000,
    22000000,
    24000000,    
    27000000,    
    32000000,
    40000000,
    48000000,
    96000000,
    0
};


typedef struct 
{
    DWORD  PixelPerLine;
    DWORD  BytesPerLine;
    DWORD  LinesPerFrame;
    DWORD  PostProcInfo;
    DWORD  SkipFrames;
    DWORD  AvgTimePerFrame;
    DWORD  FramesPerSec;
} CameraDMAInfo;



// just define interfaces 

class CCameraControl 
{

protected:
    CRITICAL_SECTION *m_pcsDeviceState;
public:
    explicit CCameraControl(
        CRITICAL_SECTION *pcsDeviceState) :m_pcsDeviceState(pcsDeviceState)
        { 
        }
    virtual ~CCameraControl() 
        {
            m_pcsDeviceState = 0;
        }

    // check if hardware is available
    virtual BOOL Init(
        //VOID * pContext
        )=0;
    virtual BOOL Deinit
        ()=0;

    virtual BOOL QueryCameraPortInfo(  
        CameraPortInfo *pinfo
        )=0;
    virtual BOOL SetCameraPortInfo(  
        CameraPortInfo *pinfo
        )=0;

    virtual DWORD GetVideoFormat(
        ULONG PinId, 
        PCS_DATARANGE_VIDEO *pPDV
        )=0;
    virtual BOOL SetFormat(
        ULONG PinId, 
        PCS_VIDEOINFOHEADER pCS,
        CameraDMAInfo *pDMAInfo
        )=0;

    virtual DWORD GetVideoControlCaps(
        ULONG PinId
        )=0;
    virtual BOOL Pause  (
        ULONG PinId
        )=0;
    virtual BOOL Run    (
        ULONG PinId
        )=0;
    virtual BOOL Stop   (
        ULONG PinId
        )=0;

    virtual BOOL Power  (
        CEDEVICE_POWER_STATE newPowerState
        )=0;

    virtual BOOL SetVidProcAmp( 
        ULONG PropId, 
        LONG value,
        BOOL manual
        )=0;
    virtual BOOL SetCameraControl( 
        ULONG PropId, 
        LONG value,
        BOOL manual 
        )=0;
    
    virtual BOOL CameraCaps (
        ULONG *ManualFlags,
        ULONG *AutoFlags
        )=0;
    virtual BOOL CameraPropertyDefault (
        ULONG PropId, 
        LONG *pDefault,
        CSPROPERTY_STEPPING_LONG *pStepping
        )=0;

    virtual VOID DumpJpegRegs()=0;

    virtual VOID SetFlash(BOOL bEnable) = 0;
    
    virtual BOOL IsCaptureMode()=0;

    virtual BOOL CachedIsCaptureMode()=0;
    
    virtual BOOL GetCurrentRes(ULONG PinId, DWORD *pWidth, DWORD *pHeight)=0;
    
    // just allocate derived class with hardware implementation
    /*static CCameraControl *PDDCAM_New(
        CRITICAL_SECTION *pcsDeviceState
        );*/

    virtual BOOL GetZoomRatio(float* pZoomRatio) = 0;
    virtual void SetFlickerFreq(DWORD dwFlickerFreq) = 0;
}; 

class CCameraPort 
{
protected:
    CRITICAL_SECTION *m_pcsDeviceState;
public:
    explicit CCameraPort(
        CRITICAL_SECTION *pcsDeviceState
        ) :m_pcsDeviceState(pcsDeviceState) 
        { 
        }
    virtual ~CCameraPort() 
        {
            m_pcsDeviceState = 0;
        }
	virtual SetCameraControl( 
                    ULONG PropId, 
                    LONG value,
                    BOOL manual 
                    ){};

    // check if hardware is available
    virtual BOOL Init(
        VOID * pContext, 
        CCameraControl *pCCtrlEx
        )=0;
    /*
    virtual BOOL Deinit
        ()=0;
        */
    virtual BOOL SetVideoControlCaps(
        ULONG PinId,
        ULONG Caps
        )=0;
    virtual BOOL SetFormat(
        ULONG PinId, 
        PCS_VIDEOINFOHEADER pCS
        )=0;

    // alloc/free resources, clock domains etc.
    virtual BOOL Prepare( 
        ULONG PinId, 
        IRQ_CALLBACK lpThread, 
        LPVOID lpContext
        )=0;
    virtual BOOL Unprepare(
        ULONG PinId
        )=0;

    virtual BOOL Pause  (
        ULONG PinId
        )=0;
    virtual BOOL Run    (
        ULONG PinId
        )=0;
    virtual BOOL Stop   (
        ULONG PinId
        )=0;

    virtual DWORD GetVideoFormat( 
        ULONG PinId, 
        PCS_DATARANGE_VIDEO *pPDV
        )=0;

    virtual BOOL Power  (
        CEDEVICE_POWER_STATE newPowerState
        )=0;

    virtual void BufferFill(
        ULONG PinId,
        PCS_VIDEOINFOHEADER pCsVideoInfoHdr,
        PCSSTREAM_HEADER pCsStreamHeader,
        PCS_FRAME_INFO   pCsFrameInfo,
        PVOID            pPDDContext
    )=0;

     virtual BOOL SetJpegCompression ( LONG Quality)=0;

      virtual BOOL GetJpegCompression ( LONG *Quality)=0;


    // just allocate derived class with hardware implementation
    static CCameraPort *PDDINT_New(
        CRITICAL_SECTION *pcsDeviceState
        );

    virtual BOOL PmPower  (CEDEVICE_POWER_STATE newPowerState)=0;
    virtual CEDEVICE_POWER_STATE    GetSysPowerState()= 0 ;
    virtual BOOL GetZoomRatio(float* pZoomRatio)=0;
    virtual void SetCameraMode(CAMERA_MODE_DESC *pStruFrame) = 0;
    virtual BOOL SetCapSeriel(TCHAR* pszName)=0;
    virtual DWORD MaxNumOfBuffers()=0;
    virtual BOOL Enqueue(DWORD dwPhyAddr, DWORD dwVirtAddr)=0;
    virtual void SetCamera(CCameraControl *pCtrl) = 0;
}; 

class CCameraSwitch
{
public:
    explicit CCameraSwitch() {};
    virtual CCameraControl *Init(CRITICAL_SECTION *pcsDeviceState) = 0;
    virtual CCameraControl *Switch() = 0;
    virtual CCameraControl *Reset() = 0;
    virtual ~CCameraSwitch() {};
    static CCameraSwitch *PDDSwitch_New();
};

#endif  //__CAMPDD_H_INCLUDED__



